<template>
  <div>
    <el-card style="margin: 20px 0px">
      <CategorySelect @getCategoryId="getCategoryId" :show="!isShowTable"></CategorySelect>
    </el-card>
    <el-card>
      <!-- - 当`isShowTable`为`true`时,<div>会被显示出来, 当`isShowTable`为`false`时,<div>会被隐藏起来
             v-show指令的作用就是根据表达式的真假值,切换元素的显示和隐藏。 -->
      <div v-show="isShowTable">
        <el-button type="primary" icon="el-icon-plus" :disabled="!category3Id" @click="addAttr">添加属性</el-button>
        <!-- 平台属性展示表格 label标题 prop内容数据-->
        <el-table style="width: 100%" border :data="attrList">
          <el-table-column type="index" label="序号" width="80" align="center">
          </el-table-column>
          <el-table-column prop="attrName" label="属性名称" width="150">
          </el-table-column>
          <el-table-column prop="prop" label="属性值列表" width="width">
            <!-- 作用域插槽 -->
            <template slot-scope="{row,$index}">
              <el-tag type="success" v-for="(attrValue, index) in row.attrValueList" :key="attrValue.id"
                style="margin:5px 12px">
                {{ attrValue.valueName }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="prop" label="操作" width="150">
            <template slot-scope="{ row,$index }">
              <el-button type="warning" icon="el-icon-edit" size="mini" @click="updateAttr(row)"></el-button>
              <el-button type="danger" icon="el-icon-delete" size="mini"></el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!-- 添加属性 | 修改属性结构 -->
      <div v-show="!isShowTable">
        <el-form ref="form" :inline="true" label-width="80px">
          <el-form-item label="属性名">
            <el-input placeholder="请输入属性名" v-model="attrInfo.attrName" ></el-input> 
          </el-form-item>
        </el-form>
        <el-button type="primary" icon="el-icon-plus" @click="addAttrValue"
          :disabled="!attrInfo.attrName">添加属性值</el-button>

        <!--  属性值列表 -->
        <el-table style="width:100%;margin:20px 0" border :data="attrInfo.attrValueList">
          <el-table-column width="80" align="center" type="index" label="序号">
          </el-table-column>
          <el-table-column width="width" label="属性值名称" prop="prop">
            <!-- row数组的每个元素 -->
            <!--  通过 flag 控制编辑交互的显示
                  使用作用域插槽获取每个属性值对象
                   编辑完成后通过方法控制交互形式的切换 -->
            <template slot-scope="{row,$index}">
              <el-input v-model="row.valueName" size="mini" placeholder="请输入属性值名称"
              v-if="row.flag" @blur="flag" @keyup.native.enter="tolook(row)" :ref="$index"
              ></el-input>
              <span v-else @click="row.flag=true" style="display: block">{{row.valueName}}</span>
            </template>

          </el-table-column>
          <el-table-column width="width" label="操作" prop="prop">
            <!-- row数组的每个元素,删除属性值 -->
            <template slot-scope="{row,$index}">
             <!-- 气泡确认框 -->
             <el-popconfirm
                :title="`确定删除${row.valueName}?`"
                @onConfirm="deleteAttrValue($index)"
              >
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  slot="reference"
                ></el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
        <el-button type="primary" @click="addOrUpdateAttr"
          :disabled="attrInfo.attrValueList.length<1" >保存</el-button>
        <el-button @click="isShowTable = true">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
import cloneDeep from 'lodash/cloneDeep' // 引入深拷贝
import router from "@/router";// 引入路由

export default {
  name: "Attr",
  data: function () {
    return {
      category1Id: '', // 一级分类的id
      category2Id: '', //  二级分类的id
      category3Id: '',  // 三级分类的id
      isShowTable: true, // 是否展示平台属性表格
      attrList: [], // 平台属性数组
      //收集新增属性 | 修改属性
      attrInfo: {
        attrName: '', // 属性名
        attrValueList: [ ], // 属性值列表 
        categoryId: 0, // 分类ID
        categoryLevel: 3,// 分类级别
      }

    };
  },
  methods: {
    // 自定义事件回调 区分一级分类 二级分类 三级分类ID
    getCategoryId({ categoryId, level }) {
      // console.log(categoryId)
      // 区分 一级ID 二级ID 三级ID level
      if (level = 1) {
        this.category1Id = categoryId
        this.category2Id = ''
        this.category3Id = ''
      } else if (level = 2) {
        this.category2Id = categoryId
        this.category3Id = ''
      } else {
        this.category3Id = categoryId
        // 三级分类ID确认 发起请求
        this.getAttrList()
      }
    },
    // 获取平台属性数组
    async getAttrList() {
      //  获取三级分类 发请求发送数据
      //  获取分类ID
      const { category1Id, category2Id, category3Id } = this;
      let result = await this.$API.attr.reqAttrList(
        category1Id,
        category2Id,
        category3Id
      );
      //  发送请求
      if (result.code === 200) {
        this.attrList = res.data.data // 获取平台属性数组
      }
    },
    // 添加属性值回调
    addAttrValue() {
      // 1.收集属性值
      // 2.添加到属性值列表
      this.attrInfo.attrValueList.push({
        valueName: "",// 属性值
        attrId: undefined,
        flag: true // 控制编辑交互的显示
      });
    },

    addAttr() {
      this.isShowTable = false
      // 清除数据
      // 清除数据
      this.attrInfo = {
        attrName: "",
        attrValueList: [],
        categoryId: this.category3Id,//此处category3Id已有 可以收集
        categoryLevel: 3,
      }
    },
  // 添加或修改属性
  // 添加属性值回调
  addAttrValue() {
      // 向属性值数组添加元素
      this.attrInfo.attrValueList.push({
        // 响应式数组
        // attrId 相应属性Id  valueName相应属性值名称
        attrId: this.attrInfo.id, //对于修改产品属性 新增新的属性 需要带上已有ID
        valueName: "",
        // 不要将flag放在data里  而是在添加属性值方法里添加flag 这样添加的每一个属性值都有独立的flag
        flag: true,
      });
      this.$nextTick(() => {
        this.$refs[this.attrInfo.attrValueList.length - 1].focus(); //获取相应表单元素并聚焦
      });
    },
    // 修改属性attr回调
    updateAttr(row) {
      // console.log(row)
      this.isShowTable = false;
      // 将选中属性赋值给attrInfo
      // 数据结构指向同一对象 attrInfo和attrValueList 修改一方为不影响另一方 使用...解析
      // 引入lodash中的深拷贝
      this.attrInfo = cloneDeep(row);
      // 没有flag标记 无法切换
      // 修改属性时 将相应属性值添加上flag标记
      this.attrInfo.attrValueList.forEach((item) => {
        // item.flag = false;直接赋值不行 非响应式数据 实现响应式 $set
        // Vue 无法探测新增的普通属性 $set(对象 添加新的属性 参数新的属性值)
        this.$set(item, "flag", false);
      });
    },
    // 失去焦点 切换为查看模式 展示span
    toLook(row) {
      // 对用户输入筛选
      // row此处为当前用户添加的属性值
      // 若输入为空 不能作为属性值 提示输入正确属性值
      if (row.valueName.trim() == "") {
        this.$message("请输入正确属性值");
        return;
      }
      // 若输入属性值与之前重复 提示
      let isRepeat = this.attrInfo.attrValueList.some((item) => {
        // 将当前row从数组里面判断时去除
        if (row !== item) {
          return row.valueName == item.valueName;
        }
      });
      // console.log(isRepeat)
      if (isRepeat) return; //重复 返回null
      row.flag = false;
    },
    toEdit(row, $index) {
      row.flag = true;
      // 获取input节点实现自动聚焦
      // console.log(this.$refs[index])
      // 点击span 切换为input变为编辑模式 页面重排 需要消耗时间不能立即获取到index 使用$nextTick
      // $nextTick  当节点渲染完毕 执行一次
      this.$nextTick(() => {
        this.$refs[index].focus(); //获取相应表单元素并聚焦
      });
    },
    // 气泡确认框回调
    deleteAttrValue($index) {
      this.attrInfo.attrValueList.splice(index, 1);
    },
    // 保存按钮 进行添加属性 或者修改属性操作
    async addOrUpdateAttr() {
      // 整理参数 1用户添加空属性值时 不提交给服务器
      // 提交服务器数据应去除flag字段
      this.attrInfo.attrValueList = this.attrInfo.attrValueList.filter(
        (item) => {
          // 返回一个新的数组 遍历每一个参数筛选符合的数据
          if (item.valueName != "") {
            // 删除掉flag属性
            delete item.flag;
            return true;
          }
        }
      );
      // 发请求
      try {
        await this.$API.attr.reqAddOrUpdateAttr(this.attrInfo);
        // 展示平台属性切换
        this.isShowTable = true;
        this.$message({
          type: "success",
          message: "保存成功",
        });
        // 重新获取保存后的数据 等待页面重排
        this.getAttrList();
      } catch (error) {
        this.$message("保存失败");
      }
    },
  },

  }

</script>

<style lang='less' scoped>

</style>
